package com.zwj.project.service.impl.inner;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zwj.project.common.ErrorCode;
import com.zwj.project.constant.RedisConstant;
import com.zwj.project.exception.BusinessException;
import com.zwj.project.mapper.UserMapper;
import com.zwj.common.model.entity.User;
import com.zwj.common.service.InnerUserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 内部用户服务实现类
 *
 * @author zwj
 */
@DubboService
public class InnerUserServiceImpl implements InnerUserService {

    @Resource
    private UserMapper userMapper;

    private static final long fiveMinutes = 1000 * 60 * 5;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public User getInvokeUser(String accessKey) {
        if (StringUtils.isAnyBlank(accessKey)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("accessKey", accessKey);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public boolean isUsedNonce(String accessKey, String nonce) {
        String key = RedisConstant.IS_USER_NONCE + accessKey;
        boolean hasKey = Objects.requireNonNull(stringRedisTemplate.hasKey(key));
        if (!hasKey) {
            stringRedisTemplate.opsForSet().add(key, String.valueOf(Long.MAX_VALUE));
            stringRedisTemplate.expire(key, fiveMinutes, TimeUnit.MILLISECONDS);
            return false;
        }
        Boolean member = Objects.requireNonNull(stringRedisTemplate.opsForSet().isMember(key, nonce));
        if (!member) {
            nonceAddToSet(accessKey, nonce);
        }
        return member;
    }

    private void nonceAddToSet(String accessKey, String nonce) {
        String key = RedisConstant.IS_USER_NONCE + accessKey;
        stringRedisTemplate.opsForSet().add(key, nonce);
    }
}
